﻿#define ON_MOBILE_PLATFORM
using UnityEngine;


public class GUIScript : MonoBehaviour {	
	public Transform checkmateSprite;
	public int currentTime;
	public int currentScore;
	public int currentJoker;
	
	private int startTime;
	private int timerInit;
	private int timerOffset;
	private MatchChecker _checker;
	private TilesGenerator _gen;
	private HighScoreScript _hs;
	private int gameStatus;
	private const int ONGOING = 0;
	private const int PAUSE = 1;
	private const int READY2PLY = 2;
	private const int TIMER_LABEL = 3;
	private const int LABEL = 4;
	private const int GAMEOVER = 5;
	private const int CHECKMATE = 6;
	private const int GET_HIGHSCORE = 7;
	private const int DISPLAY_HIGHSCORE = 8;
	#if(ON_MOBILE_PLATFORM)
		private TouchScreenKeyboard keyboard = null;
	#endif
	private string playerName;
	
	//List of the background images
	private Texture2D[] bgd;
	
	//Dimensions of the HighScore table	
	float buttonHeight = 0;
	float letterWidth = 0;
	float groupWidth = 0;
	float groupHeight = 0;
	float groupX = 0;
	float groupY = 0;
	string tmpName;
	
	//Styling of the buttons
	public GUIStyle scoreButtonStyle;
	public GUIStyle newScoreStyle;
	public GUIStyle deactivatedButtonStyle;
	private GUIStyle commonTextStyle;
	private GUIStyle rdyButtonStyle;
	private float delta;

	// Use this for initialization
	void Awake()
	{
		_checker = this.gameObject.GetComponent<MatchChecker>();
		_gen = this.gameObject.GetComponent<TilesGenerator>();
		_hs = this.gameObject.GetComponent<HighScoreScript>();
		
		playerName = "";
		scoreButtonStyle.fontSize = Screen.width/30;
		
		commonTextStyle = new GUIStyle(scoreButtonStyle);
		commonTextStyle.fontSize = Screen.width/40;
		deactivatedButtonStyle.fontSize = Screen.width/40;
		rdyButtonStyle = new GUIStyle(newScoreStyle);
		rdyButtonStyle.fontSize = Screen.width/20;


		letterWidth = 0.7f*commonTextStyle.fontSize;
		buttonHeight = Screen.height/14;
		delta = (float)4/3;
		
		bgd = Resources.LoadAll<Texture2D>("Bgds") as Texture2D[];

		/*isPlatformMobile = (Application.platform == RuntimePlatform.Android
							|| Application.platform == RuntimePlatform.IPhonePlayer );*/
		
		timerInit = 245;			//ddd ttt we do 245 because nextgame removes 15sec
		currentScore = 0;
		currentJoker = 2;

		setCamera();
		PrepareNextGame();
		StartGame();
		//_hs.ResetScores();	ddd
	}
	
	void setCamera()
	{
		
		// float allScreenShowHeight = Screen.height/oneUnityUnitPixel/2.0f;
		//// float nativeResolutionWidth =
		/*float myScaleX = Screen.width  nativeResolutionWidth;
		float myScaleY = Screen.height *1.0f / nativeResolutionHeight;*/
		
		/* Règle:
		var height = 2*Camera.main.orthographicSize;
		var width = height*Camera.main.aspect;
		
		Donc width = Camera.main.aspect * 2 * Camera.main.orthographicSize = gameWidth()
		
				
		*/
		Camera.main.aspect = (float)Screen.width/(float)Screen.height;
		Camera.main.orthographicSize = _gen.gameWidth()/2/Camera.main.aspect;
		
		// scaleX =
		// float nativeAspect = (float)nativeResolutionWidth / nativeResolutionHeight;
		/*float currentAspect = Screen.width / Screen.height;
		
		if (myScaleX > myScaleY)
			mainCamera.orthographicSize = nativeResolutionHeight / 2.0f / oneUnityUnitPixel;
		else
			mainCamera.orthographicSize = nativeResolutionWidth/oneUnityUnitPixel*(1.0f/currentAspect)/2.0f;*/
	}

	public void StartGame()
	{
		_gen.ShowTiles();
		startTime = (int) Time.time;
		timerOffset = timerInit;
		gameStatus = ONGOING;
	}
	
	public void PauseGame()
	{
		_gen.HideTiles();
		gameStatus = PAUSE;
		timerOffset = currentTime;
	}
	
	public void UnPauseGame()
	{
		_gen.ShowTiles();
		gameStatus = ONGOING;
		startTime = (int) Time.time;
	}

	void OnGUI ()
	{
		//GUI.color = Color.white;
		if( GUI.Button( new Rect( (Screen.width - 3*letterWidth),Screen.height-buttonHeight,
		                         3*letterWidth, buttonHeight),"X",commonTextStyle) )
			Application.Quit();
		
		          
		switch(gameStatus)
		{
			case READY2PLY:
				if ( GUI.Button( new Rect( 0,0,Screen.width, Screen.height), "Cliquez!",rdyButtonStyle) )
					StartGame();
				break;

			case ONGOING:
				GUIStyle tmpStyle = null;
				string tmpLabel = null;
				switch(currentJoker)
				{
					case 0:
						GUI.Button( new Rect( Screen.width / 3 - ((9+2)*letterWidth/ 2), Screen.height - buttonHeight,
				                     (7+2)*letterWidth, buttonHeight), "0  Joker...",deactivatedButtonStyle);
				        break;
				    case 1:
						tmpStyle = commonTextStyle;
				    	tmpLabel = "  Joker !";
				    	goto case 666;
				    	
				    case 666:
						if ( GUI.Button( new Rect( Screen.width / 3 - ((7+2)*letterWidth/ 2), Screen.height - buttonHeight,
					                          (7+2)*letterWidth, buttonHeight), currentJoker+tmpLabel,tmpStyle) )
					        // On button press we use a joker and check that the next one has been found
							if(!_checker.UseJoker())
								// If not, the game is over
								if( _gen.NumberOfTiles > 0 )
									Checkmate();
								else
									NoTilesLeft();
						break;

					default:
						tmpStyle = commonTextStyle;
						tmpLabel = "  Jokers !";
						goto case 666;
					}
			
	
				
				if ( GUI.Button( new Rect( 2*Screen.width / 3 - (5+2)*letterWidth/2, Screen.height - buttonHeight,
			                          (5+2)*letterWidth, buttonHeight), "Pause",commonTextStyle) )
				{
		          	PauseGame();
		          	break;
	          	}
				goto case TIMER_LABEL;
				
			case CHECKMATE:
				// The timer is being unrolled by UnrollTimer() we just keep displaying it
				goto case LABEL;
				                          
			case TIMER_LABEL:
				currentTime = (int) (timerOffset + startTime - Time.time);
				// If we are in checkmate, the timer = 0 case is delt with by the unroll function
				if( 0 >= currentTime ) //&& CHECKMATE != gameStatus )
					GameOver();
				goto case LABEL;
			
			case PAUSE:
				if ( GUI.Button( new Rect( 0,0,Screen.width, Screen.height), "Pause",scoreButtonStyle) )
					UnPauseGame();
				goto case LABEL;
				
			case GAMEOVER:
				if ( GUI.Button( new Rect( 0,0,Screen.width, Screen.height),
			                "Game Over\nYour Score: "+currentScore,scoreButtonStyle) )
					Application.LoadLevel("Menu");
				break;
				
			case GET_HIGHSCORE:
				#if(ON_MOBILE_PLATFORM)
					if( GUI.Button( new Rect( Screen.width / 2 - ((10+2)*delta*letterWidth / 2), Screen.height/2 - delta*buttonHeight,
				                    (10+2)*delta*letterWidth, delta*buttonHeight), "Enter Name",scoreButtonStyle) )
						keyboard = TouchScreenKeyboard.Open(playerName, TouchScreenKeyboardType.Default);
						
					if( null != keyboard )
						if( keyboard.done )
						{
							grabNameAndCalculateHSPanelDimensions();
							gameStatus = DISPLAY_HIGHSCORE;
						}
				#else
					GUI.Button( new Rect( Screen.width / 2 - ((9+2)*delta*letterWidth / 2), Screen.height/2,
				                     (9+2)*delta*letterWidth, delta*buttonHeight), "Your Name",scoreButtonStyle);

					GUI.SetNextControlName("nameTextField");
					playerName = GUI.TextField( new Rect (Screen.width / 2 - (playerName.Length+2)*delta*letterWidth/2,
				                           				Screen.height/2+delta*buttonHeight,
				                           				Mathf.Max(3,playerName.Length+2)*delta*letterWidth,
				                           				delta*buttonHeight),
				                           				playerName,scoreButtonStyle);
					GUI.FocusControl("nameTextField");

			    	if (Event.current.keyCode == KeyCode.Return )
			    	{
						grabNameAndCalculateHSPanelDimensions();
						gameStatus = DISPLAY_HIGHSCORE;
					}
				#endif
				break;
				
			case DISPLAY_HIGHSCORE:

				// The whole background is a RESTART button
				if( GUI.Button(new Rect(0,0,Screen.width,Screen.height),"") )
					Application.LoadLevel("Menu");

				GUI.BeginGroup( new Rect( groupX, groupY, groupWidth, groupHeight ) );
				GUI.Box( new Rect( 0, 0, groupWidth, groupHeight ),"");
				
				GUI.Label( new Rect( delta*letterWidth, delta*buttonHeight/2,
			                   0.9f*groupWidth, delta*buttonHeight), "BEST SCORES", scoreButtonStyle);
				int n = 0;
				while(PlayerPrefs.HasKey(n+"HScore") )
				{
					tmpName = PlayerPrefs.GetString(n+"HScoreName");
					if( "" == tmpName)
						break;
					
					GUI.Label( new Rect( delta*letterWidth, (n+2)*delta*buttonHeight,
								0.9f*groupWidth, delta*buttonHeight), 
					          PlayerPrefs.GetString(n+"HScoreName")+"      "+ PlayerPrefs.GetInt(n+"HScore"),
					          (0 == string.Compare(tmpName,playerName))?newScoreStyle:scoreButtonStyle);
					n++;
				}
				GUI.EndGroup();
				break;
				
				
			case LABEL:
				// The width of the label is: the number of characters + 2 for the sides
				GUI.Label( new Rect( Screen.width / 3 - (8+Mathf.Log10(currentTime+1))*letterWidth/2, 0,
			                    (8+Mathf.Log10(currentTime+1))*letterWidth,buttonHeight), "Time: "+ currentTime,commonTextStyle);

				GUI.Label( new Rect( 2 * Screen.width / 3 - (9+Mathf.Log10(currentScore+1))*letterWidth/2, 0,
			                    (9+Mathf.Log10(currentScore+1))*letterWidth,buttonHeight),
			                    	"Score: "+ currentScore,commonTextStyle);
				break;

			default:
				break;
		}
	}
	
	
	void Checkmate()
	{
		// We make the checkmate sprite invisible
		gameStatus = CHECKMATE;
		checkmateSprite.renderer.enabled = true;
		_gen.deactivateTilesColliders();
		UnrollTimer();
	}
	
	void UnrollTimer()
	{
		// Function is used both for checkmate and when no tiles are left.
		// For both cases, the clock is stopped, hence the chkmate status.
		gameStatus = CHECKMATE;	
		if( 0 > 4 + currentTime )
		{
			PrepareNextGame();
			return;
		}
		else
		{
			currentTime -= 5;
			currentScore += 50;
			Invoke("UnrollTimer",0.05f);
		}
	}
	
	void PrepareNextGame()
	{
		//We hide the checkmate and the tiles
		//if( checkmateSprite.renderer.enabled )
		checkmateSprite.renderer.enabled = false;
		_gen.HideTiles();
		
		
		//Once the tiles are hidden we shuffle them, they will reappear on game start
		_gen.Distribute();
		
		// We then load the beautiful background for between the games and tell the gui we're good to go
		rdyButtonStyle.normal.background = bgd[Random.Range(0,bgd.Length-1)];
		gameStatus = READY2PLY;
		if( 40 < timerInit)
			timerInit -= 15;
		currentJoker += 1;
	}
	
	void Update()
	{
		if( Input.GetButtonDown("Pause") )
			if( ONGOING == gameStatus )
				PauseGame();
			else if( PAUSE == gameStatus )
				UnPauseGame();
	}
	
	public void NoTilesLeft()
	{
		_gen.deactivateTilesColliders();
		UnrollTimer();
	}
	
	void GameOver()
	{
		_gen.deactivateTilesColliders();
		if( _hs.IsHighScore(currentScore) )
		{
			_hs.isHighScore = true;
			gameStatus = GET_HIGHSCORE;
		}
		else
			gameStatus = GAMEOVER;
	}
	
	void grabNameAndCalculateHSPanelDimensions()
	{
		string tmpScore;
		//Store the name and hide the keyboard
		#if(ON_MOBILE_PLATFORM)
		if( null != keyboard)
			playerName = keyboard.text;
		keyboard = null;
		#endif
		
		_hs.AddScore(playerName,currentScore);
		
		// Reset the name for the next time
		playerName = "";
		
		//Calculate the dimensions of the HSPanel
		int numberOfScores = 0;
		// The minimal width should be enough to write "Best Scores" at the top, with one free char on each side
		float longerName = 13;
		
		for(int n = 0; n < _hs.maxNumberOfScores; n++)
		{
			if(PlayerPrefs.HasKey(n+"HScore"))
			{
				tmpName = PlayerPrefs.GetString(n+"HScoreName");
				tmpScore = PlayerPrefs.GetInt(n+"Hscore").ToString();
				if(tmpName != "")
				{
					numberOfScores++;
					longerName = Mathf.Max(longerName,tmpName.Length+6+tmpScore.Length);
				}
			}
		}
		groupWidth = Mathf.Min((longerName+2)*delta*letterWidth,2*Screen.width/3);
		groupHeight = delta*buttonHeight*(numberOfScores + 2.5f);
		
		groupX = ( Screen.width - groupWidth ) / 2;
		groupY = ( Screen.height - groupHeight ) / 2;
	}
}
